package com.dq.service.order.impl;

import com.dq.context.Constant;
import com.dq.exception.customException.AdminException;
import com.dq.controller.in.orders.ShortageOrderQuery;
import com.dq.controller.in.orders.ShortageOrderSave;
import com.dq.domain.orders.*;
import com.dq.domain.orders.info.OrderInfo;
import com.dq.domain.org.Org;
import com.dq.domain.sys.user.user.base.SysUser;
import com.dq.repository.BaseRepositories;
import com.dq.service.order.ShortageOrderService;
import com.dq.service.org.OrgService;
import com.dq.service.sys.user.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author liuhui
 * @date 2019/11/27 0027 14:12:33
 */
@Service
public class ShortageOrderServiceImpl extends BaseRepositories implements ShortageOrderService {
    @PersistenceContext
    private EntityManager entityManager;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private OrgService orgService;


    @Override
    public List<ShortageOrder> findByWhere(ShortageOrderQuery shortageOrderQuery, Org org) throws AdminException {
        StringBuilder hql = new StringBuilder("select u from ShortageOrder u where u.deleted=false");
        Query q = createWhereHql(shortageOrderQuery,org,hql);
        q.setFirstResult((shortageOrderQuery.getPage()-1)*shortageOrderQuery.getSize());
        q.setMaxResults(shortageOrderQuery.getSize());
        List<ShortageOrder> shortageOrders = q.getResultList();
        return shortageOrders;
    }

    @Override
    public Long countByWhere(ShortageOrderQuery shortageOrderQuery, Org org) throws AdminException {
        StringBuilder hql = new StringBuilder("select count(u) from ShortageOrder u where u.deleted=false");
        Query q = createWhereHql(shortageOrderQuery,org,hql);
        return new Long((long) q.getResultList().get(0));
    }

    public Query createWhereHql(ShortageOrderQuery shortageOrderQuery,Org org,StringBuilder hql) throws AdminException {
        if(org != null) {
            hql.append(" and u.org =:org");
        }else {
            // 只显示负责门店信息
            String orgIdsIn = orgService.getIdListAllByUser();
            if(StringUtils.isNotBlank(orgIdsIn)) {
                hql.append(" and u.org.id in ").append(orgIdsIn);
            }
        }

        if(shortageOrderQuery.getShortageType() != null && !shortageOrderQuery.getShortageType().toString().equals(ShortageOrder.ShortageType.all.toString())) {
            hql.append(" and u.shortageType =:shortageType");
        }

        if(StringUtils.isNotEmpty(shortageOrderQuery.getShortageOrderNo())){
            hql.append(" and u.ordersNo like:ordersNo");
        }
        if(StringUtils.isNotEmpty(shortageOrderQuery.getRelateOrderNo())){
            hql.append(" and u.relateOrder.ordersNo like:relateOrderNo");
        }
        if(null!=shortageOrderQuery.getBeginTime()){
            hql.append(" and u.createTime >=:beginTime");
        }
        if(null!=shortageOrderQuery.getEndTime()){
            hql.append(" and u.createTime <=:endTime");
        }
        if(null!=shortageOrderQuery.getShortageStatus()){
            hql.append(" and u.shortageStatus =:status");
        }

        hql.append(" order by u.id desc");

        Query query = entityManager.createQuery(hql.toString());
        if(org != null) {
            query.setParameter("org",org);
        }
        if(shortageOrderQuery.getShortageType() != null && !shortageOrderQuery.getShortageType().toString().equals(ShortageOrder.ShortageType.all.toString())) {
            query.setParameter("shortageType", shortageOrderQuery.getShortageType());
        }
        if(StringUtils.isNotEmpty(shortageOrderQuery.getShortageOrderNo())){
            query.setParameter("ordersNo","%"+shortageOrderQuery.getShortageOrderNo()+"%");
        }
        if(StringUtils.isNotEmpty(shortageOrderQuery.getRelateOrderNo())){
            query.setParameter("relateOrderNo","%"+shortageOrderQuery.getRelateOrderNo()+"%");
        }
        if(null!=shortageOrderQuery.getBeginTime()){
            query.setParameter("beginTime",shortageOrderQuery.getBeginTime());
        }
        if(null!=shortageOrderQuery.getEndTime()){
            query.setParameter("endTime",shortageOrderQuery.getEndTime());
        }
        if(null!=shortageOrderQuery.getShortageStatus()){
            query.setParameter("status",shortageOrderQuery.getShortageStatus());
        }
        return query;
    }

    /**
     *  缺货单 生成逻辑
     * @param shortageOrderSave
     * @return
     * @throws AdminException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ShortageOrder manualSave(ShortageOrderSave shortageOrderSave) throws AdminException {
        if(shortageOrderSave.getShortageType() == null || shortageOrderSave.getShortageType().toString().equals(ShortageOrder.ShortageType.all.toString())) {
            throw new AdminException("shortageType 不能为空或等于all ");
        }

        if(shortageOrderSave.getOrdersId() == null) {
            throw new AdminException("采购单/销售单id获取异常");
        }
        List<ShortageOrderSave.ShortageOrderInfo> returnInfoList = shortageOrderSave.getReturnInfoList();
        if(returnInfoList == null || returnInfoList.size() <= 0) {
            throw new AdminException("商品集合为空");
        }

        Map<String, Object> query = new HashMap<>(16);
        query.put("orders_id", shortageOrderSave.getOrdersId());
        List<OrderInfo> orderInfos = dao.find(dao.query2Hql(OrderInfo.class, query), query);
        if(orderInfos == null || orderInfos.size() <= 0) {
            throw new AdminException("无对应采购单详情信息");
        }
        Orders orders = orderInfos.get(0).getOrders();
        if(orders instanceof OrgOrder) {
            OrgOrder od = (OrgOrder) orders;
            if(!od.getOrgOrderStatus().toString().equals(OrgOrder.OrgOrderStatus.orgPass.toString())) {
                throw new AdminException("采购单状态未门店确认，不能生成缺货单");
            }
        }

        ShortageOrder shortageOrder = new ShortageOrder();
        shortageOrder.setShortageType(shortageOrderSave.getShortageType());
        shortageOrder.setRelateOrder(orders);
        shortageOrder.setShortageStatus(ShortageOrder.ShortageStatus.notReplenish);

        BigDecimal price = new BigDecimal("0");
        List<OrderInfo> orderInfoList = new ArrayList<>();
        for (OrderInfo orderInfo : orderInfos) {
            if(orderInfo.getProduct() == null || orderInfo.getProduct().getId() == null) {
                throw new AdminException("详情未关联product");
            }
            for (ShortageOrderSave.ShortageOrderInfo shortageOrderInfo : returnInfoList) {
                Long productId = shortageOrderInfo.getProductId();
                Long count = shortageOrderInfo.getReturnCount();
                if(orderInfo.getProduct().getId().toString().equals(productId.toString())) {
                    if(count > orderInfo.getNumber()) {
                        throw new AdminException(orderInfo.getProduct().getGoods().getGoodsName() + ", 输入数量大于实际采购数量");
                    }
                    OrderInfo orderInfoSave = new OrderInfo();
                    orderInfoSave.setOrders(shortageOrder);
                    orderInfoSave.setProduct(orderInfo.getProduct());
                    orderInfoSave.setGoods(orderInfo.getGoods());
                    orderInfoSave.setNumber(count);
                    orderInfoSave.setAmount(orderInfo.getProduct().getPrice().multiply(new BigDecimal(String.valueOf(count))).setScale(2, RoundingMode.HALF_UP));

                    orderInfoList.add(orderInfoSave);

                    price = price.add(orderInfoSave.getAmount()).setScale(2, RoundingMode.HALF_UP);
                }
            }
        }

        shortageOrder.setPrice(price);
        shortageOrder = saveMainAndInfo(shortageOrder, orderInfoList);

        return shortageOrder;
    }


    /**
     * 添加 缺货单实体 main_info
     * @param
     * @return
     * @throws AdminException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ShortageOrder saveMainAndInfo(ShortageOrder shortageOrder, List<OrderInfo> orderInfoList) throws AdminException {
        if(orderInfoList == null || orderInfoList.size() <= 0) {
            throw new AdminException("子单信息为空");
        }
        if(StringUtils.isBlank(shortageOrder.getOrdersNo())) {
            shortageOrder.setOrdersNo(Orders.generyDatetimeAndRandomNum(Constant.ORDERS_SUFF_COUNT));
        }
        if(shortageOrder.getRelateOrder() == null) {
            throw new AdminException("未关联采购单/缺货单");
        }
        if(shortageOrder.getShortageStatus() == null) {
            throw new AdminException("状态异常");
        }
        if(shortageOrder.getPrice() == null) {
            throw new AdminException("金额为空");
        }

        shortageOrder.setVersion(Constant.VERSION_VALUE);
        shortageOrder.setDeleted(false);
        shortageOrder.setCreateTime(System.currentTimeMillis());
        shortageOrder.setLastModifyTime(System.currentTimeMillis());

        SysUser user = sysUserService.getUser();
        shortageOrder.setCreateUser(user);
        shortageOrder.setUpdateUser(user);

        if(shortageOrder.getTradeSuccessTime() == null) {
            if(shortageOrder.getShortageStatus().name.equals(ShortageOrder.ShortageStatus.alreadyReplenish.name)) {
                // 设置完成时间
                shortageOrder.setTradeSuccessTime(System.currentTimeMillis());
            }
        }
        if(shortageOrder.getOrg() == null) {
            shortageOrder.setOrg(shortageOrder.getRelateOrder().getOrg());
        }

        Long payGoodsNum = 0L;
        List<OrderInfo> list = new ArrayList<>();
        for (OrderInfo orderInfo : orderInfoList) {
            payGoodsNum = payGoodsNum + orderInfo.getNumber();
            list.add(orderInfo);
        }
        shortageOrder.setPayGoodsNum(payGoodsNum);
        shortageOrder.setCateNum(Long.parseLong(String.valueOf(orderInfoList.size())));

        this.entityManager.persist(shortageOrder);

        for (OrderInfo orderInfo : list) {
            if(orderInfo.getOrders() == null) {
                orderInfo.setOrders(shortageOrder);
            }

            orderInfo.setVersion(Constant.VERSION_VALUE);
            orderInfo.setDeleted(false);
            orderInfo.setCreateTime(System.currentTimeMillis());
            orderInfo.setLastModifyTime(System.currentTimeMillis());

            orderInfo.setCreateUser(user);
            orderInfo.setUpdateUser(user);
            this.entityManager.persist(orderInfo);
        }

        this.entityManager.flush();

        return shortageOrder;
    }


    /**
     * 修改 缺货单
     * @param shortageOrder
     * @return
     * @throws AdminException
     */
    @Override
    public ShortageOrder update(ShortageOrder shortageOrder) throws AdminException {
        shortageOrder.setLastModifyTime(System.currentTimeMillis());

        SysUser user = sysUserService.getUser();
        if(user != null) {
            shortageOrder.setUpdateUser(user);
        }

        if(shortageOrder.getTradeSuccessTime() == null) {
            if(shortageOrder.getShortageStatus().name.equals(ShortageOrder.ShortageStatus.alreadyReplenish.name)) {
                // 设置完成时间
                shortageOrder.setTradeSuccessTime(System.currentTimeMillis());
            }
        }

        dao.modify(shortageOrder);

        return shortageOrder;
    }

}
